package com.codeworker.app.ui;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.codeworker.app.R;
import com.codeworker.app.data.AccountRoomDatabase;
import com.codeworker.app.data.common.Constant;
import com.codeworker.app.databinding.ActivityAppSettingBinding;
import com.codeworker.app.ui.wrapper.MyBaseActivity;
import com.codeworker.app.ui.wrapper.MyLoading;
import com.codeworker.app.ui.wrapper.MyPopupWindow;
import com.codeworker.app.ui.wrapper.MyPopupWindowAdapter;
import com.codeworker.app.utils.FormatUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class AppSettingActivity extends MyBaseActivity {

    private TextView tvSettingPassword;
    private TextView tvSettingInputData;
    private TextView tvSettingOutputData;
    private List<MyPopupWindowAdapter.PopupWindowViewHolderInDB> popupWindowItems;
    private View view;

    private SharedPreferences.Editor spEditor;
    private SharedPreferences spData;

    private final static int BACK_BY_FILE_ACCESS_SETTING_ACTIVITY_RESULT = 1;

    @RequiresApi(api = Build.VERSION_CODES.R)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        ActivityAppSettingBinding binding = ActivityAppSettingBinding.inflate(getLayoutInflater());
        view = binding.getRoot();
        setContentView(view);
        setToolbar(this);
        initView(view);

        tvSettingPassword.setOnClickListener(settingPasswordEvent());
        baseClickListenerForFileHandler(tvSettingInputData, this::inputDataFileHandler);
        baseClickListenerForFileHandler(tvSettingOutputData, this::outputDataFileHandler);
    }

    private void initView(View view) {
        spEditor = getSharedPreferences("SharedPreferences", MODE_PRIVATE).edit();
        spData = getSharedPreferences("SharedPreferences", MODE_PRIVATE);

        tvSettingPassword = view.findViewById(R.id.tv_setting_password);
        tvSettingInputData = view.findViewById(R.id.tv_setting_input_data);
        tvSettingOutputData = view.findViewById(R.id.tv_setting_output_data);

        setTvHintData(tvSettingPassword, "settingPassword", "settingPassword");
        setTvHintData(tvSettingInputData, "settingInputData", "settingInputData");
        setTvHintData(tvSettingOutputData, "settingOutputData", "settingOutputData");
    }

    private void setTvHintData(TextView tv, String spDefaultName, String spDataName) {
        if (spData.getString(spDefaultName, Constant.CLOSE_FINGER_PROTECT).equals(Constant.CLOSE_FINGER_PROTECT)) {
            tv.setHint(spData.getString(spDefaultName, Constant.CLOSE_FINGER_PROTECT));
            return;
        }
        tv.setHint(spData.getString(spDataName, Constant.START_FINGER_PROTECT));
    }

    @RequiresApi(api = Build.VERSION_CODES.R)
    private void baseClickListenerForFileHandler(TextView tv, FileHandler handler) {
        tv.setOnClickListener(view -> {
            if (!Environment.isExternalStorageManager()) {
                baseAlertDialog(
                        "该操作需要获取文件操作权限, 是否允许并开通?",
                        (dialogInterface, i) -> {
                            Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                            startActivityForResult(intent, BACK_BY_FILE_ACCESS_SETTING_ACTIVITY_RESULT);
                        });
                return;
            }
            handler.handler();
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void inputDataFileHandler() {
        if (!AccountRoomDatabase.EXTERN_DATA_FILE.exists()) {
            Toast.makeText(view.getContext(), AccountRoomDatabase.EXTERN_DATA_FILE_NAME +
                    "(文件不存在, 导入失败)", Toast.LENGTH_SHORT).show();
            return;
        }
        baseAlertDialog(
                "该操作会覆盖当前账本数据, 是否允许操作?",
                (dialogInterface, i) -> {
                    FileHandler.init(this);
                    try {
                        FileUtils.copy(new FileInputStream(AccountRoomDatabase.EXTERN_DATA_FILE),
                                new FileOutputStream(AccountRoomDatabase.DATA_FILE));
                    } catch (IOException e) {
                        Toast.makeText(view.getContext(), "导入失败", Toast.LENGTH_SHORT).show();
                    }
                    FileHandler.saveData(tvSettingInputData, spEditor, "settingInputData");
                    Toast.makeText(view.getContext(), "导入成功", Toast.LENGTH_SHORT).show();
                });
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void outputDataFileHandler() {
        FileHandler.init(this);
        File externDir = AccountRoomDatabase.EXTERN_DATA_FILE_DIR;
        boolean dirExist = externDir.exists();
        if (!dirExist) {
            dirExist = externDir.mkdirs();
        }
        try {
            if (dirExist) {
                FileUtils.copy(new FileInputStream(AccountRoomDatabase.DATA_FILE),
                        new FileOutputStream(AccountRoomDatabase.EXTERN_DATA_FILE));
            }
        } catch (IOException e) {
            Toast.makeText(view.getContext(), "导出失败", Toast.LENGTH_SHORT).show();
        }
        FileHandler.saveData(tvSettingOutputData, spEditor, "settingOutputData");
        Toast.makeText(view.getContext(), "导出目录: "
                + AccountRoomDatabase.EXTERN_DATA_FILE_NAME, Toast.LENGTH_LONG).show();
    }

    @FunctionalInterface
    interface FileHandler {
        static void init(Context context) {
            MyLoading.showLoadDialog(context);
            AccountRoomDatabase.closeDatabase();
        }

        void handler();

        static void saveData(TextView tv, SharedPreferences.Editor spEditor, String data) {
            MyLoading.closeDialog();
            String time = FormatUtil.format(LocalDateTime.now());
            tv.setHint(time);
            spEditor.putString(data, time);
            spEditor.apply();
        }
    }

    private void baseAlertDialog(String message, DialogInterface.OnClickListener listener) {
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("允许", listener)
                .setNegativeButton("取消", (dialogInterface, i) -> {
                    Toast.makeText(view.getContext(), "操作已取消", Toast.LENGTH_SHORT).show();
                })
                .show();
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private View.OnClickListener settingPasswordEvent() {
        return v -> {
            @SuppressLint("InflateParams") View popUpView
                    = LayoutInflater.from(this).inflate(R.layout.layout_common_popup, null);
            // 设置适配器的数据项
            ListView listView = popUpView.findViewById(R.id.lv_common_popup);

            // 初始化数据
            popupWindowItems = new ArrayList<>();
            popupWindowItems.add(new MyPopupWindowAdapter.PopupWindowViewHolderInDB(Constant.START_FINGER_PROTECT, 0));
            popupWindowItems.add(new MyPopupWindowAdapter.PopupWindowViewHolderInDB(Constant.CLOSE_FINGER_PROTECT, 1));
            MyPopupWindowAdapter adapter = new MyPopupWindowAdapter(v.getContext(), popupWindowItems);
            listView.setAdapter(adapter);

            // 设置弹窗
            MyPopupWindow myPopupWindow = new MyPopupWindow(popUpView, this, false);
            myPopupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
            // 弹窗事件监听
            listView.setOnItemClickListener(settingPasswordItemsEvent(myPopupWindow));
        };
    }

    private AdapterView.OnItemClickListener settingPasswordItemsEvent(MyPopupWindow myPopupWindow) {
        return (parent, view, position, id) -> {
            myPopupWindow.dismiss();
            String defaultPasswordStatus = popupWindowItems.get(position).getItem();
            if (Constant.CLOSE_FINGER_PROTECT.equals(defaultPasswordStatus)) {
                tvSettingPassword.setHint(Constant.CLOSE_FINGER_PROTECT);
                spEditor.putString("settingPassword", Constant.CLOSE_FINGER_PROTECT);
            }
            if (Constant.START_FINGER_PROTECT.equals(defaultPasswordStatus)) {
                tvSettingPassword.setHint(Constant.START_FINGER_PROTECT);
                spEditor.putString("settingPassword", Constant.START_FINGER_PROTECT);
            }
            spEditor.apply();
        };
    }

    @RequiresApi(api = Build.VERSION_CODES.R)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == BACK_BY_FILE_ACCESS_SETTING_ACTIVITY_RESULT) {
            if (!Environment.isExternalStorageManager()) {
                Toast.makeText(this, "权限未开通", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "权限已开通, 再次点击即可操作~", Toast.LENGTH_LONG).show();
            }
            Intent intent = new Intent(this, AppSettingActivity.class);
            startActivity(intent);
            finish();
            overridePendingTransition(0, 0);
        }
    }

}
